﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace Noris.Schedule.UI.Components
{
	public static class PicLibraryIco
	{
		#region Image TaskPin1
		/// <summary>
		/// Vrátí obrázek, vytvořený na základě obrázku TaskPin1.png.
		/// Vrací přímou referenci na objekt v paměti = volání je velice rychlé (pod 1 mikrosekundu), 
		/// ale protože se vrací živá reference, pak zásahy do vráceného objektu se projeví v objektu v paměti = natrvalo.
		/// Případně je možno vyvolat metodu TaskPin1_Reset(), která zajistí regenerování obrázku z jeho definice.
		/// Bezpečnější je používání property TaskPin1, která vrací vždy nový objekt.
		/// Pro používání pro Button.Image, kde bude nastavováno Button.Enabled = false; je třeba použít property TaskPin1_FromFile.
		/// </summary>
		/// <remarks>
		/// Plné jméno vstupního souboru:
		/// C:\David\CsProj\GreenSchedule\Schedule\pic\TaskPin1.png
		/// </remarks>
		public static System.Drawing.Image TaskPin1_Cached
		{
			get
			{
				if (_TaskPin1 == null) _TaskPin1 = TaskPin1;
				return _TaskPin1;
			}
		}
		/// <summary>
		/// Vrátí obrázek, vytvořený na základě obrázku TaskPin1.png.
		/// Nelze používat jako Image pro Buttony, kde bude nastavováno Enabled = false (pak dojde k chybě .NET: Ot of memory).
		/// Pak je třeba použít Image TaskPin1_FromFile.
		/// Vrací vždy novou instanci = volání je při častém používání výrazně (až 1000krát) pomalejší než použití TaskPin1_Cached
		/// (kde ale hrozí nebezpečí pokažení obrázku v paměti).
		/// Čas pro vytvoření jednoho Image (tj. každé jednotlivé čtení této property) pro obrázek velikosti 32x32 px (32bpp) je průměrně 350 mikrosekund.
		/// Pokud je třeba používat obrázek často a rychle, je možné využít property TaskPin1_Cached.
		/// </summary>
		/// <remarks>
		/// Plné jméno vstupního souboru:
		/// C:\David\CsProj\GreenSchedule\Schedule\pic\TaskPin1.png
		/// </remarks>
		public static System.Drawing.Image TaskPin1 { get { return _ImageCreateFrom(_TaskPin1_string, null); } }
		/// <summary>
		/// Vrátí obrázek, načtený ze souboru TaskPin1.png.
		/// Vrací vždy novou instanci = volání je při častém používání výrazně (až 1000krát) pomalejší než použití TaskPin1_Cached
		/// (kde ale hrozí nebezpečí pokažení obrázku v paměti).
		/// Čas pro vytvoření jednoho Image (tj. každé jednotlivé čtení této property) pro obrázek velikosti 32x32 px (32bpp) je průměrně 350 mikrosekund.
		/// Pokud je třeba používat obrázek často a rychle, je možné využít property TaskPin1_Cached.
		/// </summary>
		/// <remarks>
		/// Plné jméno vstupního souboru:
		/// C:\David\CsProj\GreenSchedule\Schedule\pic\TaskPin1.png
		/// </remarks>
		public static System.Drawing.Image TaskPin1_FromFile { get { return _ImageCreateFrom(_TaskPin1_string, "TaskPin1.png"); } }
		/// <summary>
		/// Vygeneruje a vrátí string, který definuje obsah souboru TaskPin1
		/// </summary>
		/// <returns></returns>
		private static string _TaskPin1_string()
		{
			System.Text.StringBuilder sb = new System.Text.StringBuilder(412);
			sb.Append("iVBORw0KGgoAAAANSUhEUgAAAA0AAAAKCAIAAADgjEOTAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3");
			sb.Append("YXJlAFBhaW50Lk5FVCB2My41LjLX7mlDAAAApElEQVQoU23QLQ7CQBAF4JFoEmQdJ0CQgOAW3AHBGajBI6HF9QQEg6wDSVBg9xid/XkMXdLAdjbj3peX7CNoz+PpUXvc");
			sb.Append("u5D6zIYdY8TIGGTDKoLUSVODzGErZzER6sJFcS7sJY6OsfhUIlf7askY8xYNGlBRzlRXWZDEraZDOTTmkTqPSrJNvrze1qfzuDhOI/pzHYqBMa/fKb7/TVB/LGU/dfk3");
			sb.Append("bNlcTJv87OMAAAAASUVORK5CYII=");
			return sb.ToString();
		}
		/// <summary>
		/// Resetuje obrázek v paměti.
		/// Následující použití property TaskPin1_Direct si vytvoří nový, korektní - podle jeho originální deklarace.
		/// Tuto metodu je vhodné použít v situaci, kdy je správnost obrázku v paměti nejistá.
		/// </summary>
		public static void TaskPin1_Reset()
		{
			_TaskPin1 = null;
		}
		/// <summary>
		/// Úložiště objektu v paměti, při prvním použití TaskPin1_Direct je objekt naplněn a následně využíván.
		/// </summary>
		private static System.Drawing.Image _TaskPin1 = null;
		#endregion
		#region SPOLEČNÉ METODY PRO KONVERZI
		/// <summary>
		/// Vrátí Image z definice (string). Image generuje buď v paměti, anebo s pomocí souboru.
		/// Pokud není zadán parametr (cacheFileName) (když je null), generuje se Image v paměti.
		/// Pokud je soubor (cacheFileName) definován, pak se Image čte z něj.
		/// Pokud soubor neexistuje, nejprve se vytvoří.
		/// Umístění souboru (adresář) je dán property _ImageCacheDir, defaultně je to adresář (Sys:\Documents and Settings\All Users\Data aplikací\IconCache).
		/// Obsah obrázku definuje metoda getDataMethod.
		/// </summary>
		/// <param name="getDataMethod"></param>
		/// <param name="cacheFileName"></param>
		/// <returns></returns>
		private static System.Drawing.Image _ImageCreateFrom(_GetStringDelegate getDataMethod, string cacheFileName)
		{
			System.Drawing.Image image;
			if (cacheFileName == null)
			{
				using (System.IO.MemoryStream ms = new System.IO.MemoryStream(Convert.FromBase64String(getDataMethod())))
				{
					image = System.Drawing.Image.FromStream(ms);
				}
				return image;
			}
			string fileName = System.IO.Path.Combine(_ImageCacheDir, cacheFileName);
			if (!System.IO.File.Exists(fileName))
				System.IO.File.WriteAllBytes(fileName, Convert.FromBase64String(getDataMethod()));
			if (System.IO.File.Exists(fileName))
				return Image.FromFile(fileName);
			return null;
		}
		/// <summary>
		/// Obsahuje jméno adresáře, který slouží jako Cache pro obrázky systému.
		/// </summary>
		private static string _ImageCacheDir
		{
			get
			{
				string dirName = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData), "IconCacheScheduleIco");
				if (!System.IO.Directory.Exists(dirName))
					System.IO.Directory.CreateDirectory(dirName);
				return dirName;
			}
		}
		/// <summary>
		/// Předpis pro metody, které generují obsah souboru s daty
		/// </summary>
		/// <returns></returns>
		private delegate string _GetStringDelegate();
		/// <summary>
		/// Vrátí Icon z dat (string), která jsou předána na vstup v kódování Base64
		/// </summary>
		/// <param name="data">Vstupní data v kódování Base64</param>
		/// <returns>Icon vytvořená z dat</returns>
		public static System.Drawing.Icon ConvertStringToIcon(string data)
		{
			System.Drawing.Icon icon;
			using (System.IO.MemoryStream ms = new System.IO.MemoryStream(Convert.FromBase64String(data)))
			{
				icon = new System.Drawing.Icon(ms);
			}
			return icon;
		}
		/// <summary>
		/// Vrátí Cursor z dat (string), která jsou předána na vstup v kódování Base64
		/// </summary>
		/// <param name="data">Vstupní data v kódování Base64</param>
		/// <returns>Cursor vytvořený z dat</returns>
		public static System.Windows.Forms.Cursor ConvertStringToCursor(string data)
		{
			System.Windows.Forms.Cursor cursor;
			using (System.IO.MemoryStream ms = new System.IO.MemoryStream(Convert.FromBase64String(data)))
			{
				cursor = new System.Windows.Forms.Cursor(ms);
			}
			return cursor;
		}
		#endregion
	}
}
